/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.grails.gradle.common

import java.nio.charset.StandardCharsets
import java.time.LocalDate
import java.time.ZoneOffset
import java.util.regex.Pattern

import groovy.transform.CompileStatic
import org.codehaus.groovy.runtime.IOGroovyMethods

@CompileStatic
final class PropertyFileUtils {

    private final static Pattern TIME_REGEX = ~'^#(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)(?:,|\\s).*$'

    private PropertyFileUtils() {
        // prevent  instantiation
    }

    static ByteArrayInputStream makePropertiesOutputReproducible(ByteArrayOutputStream propertyOutputStream) {
        List<String> lines = propertyOutputStream.toString(StandardCharsets.ISO_8859_1.name()).readLines()

        ByteArrayOutputStream toWrite = new ByteArrayOutputStream()
        toWrite.withWriter(StandardCharsets.ISO_8859_1.name()) { Writer writer ->
            BufferedWriter bufferedWriter = new BufferedWriter(writer)
            makePropertyLinesReproducible(lines, bufferedWriter)
            bufferedWriter.flush()
        }

        new ByteArrayInputStream(toWrite.toByteArray())
    }

    static void makePropertiesFileReproducible(File factoriesFile) {
        List<String> lines = factoriesFile.readLines(StandardCharsets.ISO_8859_1.name())

        factoriesFile.withWriter(StandardCharsets.ISO_8859_1.name()) { BufferedWriter writer ->
            makePropertyLinesReproducible(lines, writer)
        }
    }

    private static void makePropertyLinesReproducible(List<String> lines, BufferedWriter writer) {
        String sourceDateEpoch = determineSourceDateEpoch()

        boolean dateReplaced = false
        lines.each { String line ->
            if (!dateReplaced && TIME_REGEX.matcher(line).matches()) {
                dateReplaced = true
                IOGroovyMethods.writeLine(writer, "# SOURCE_DATE_EPOCH = $sourceDateEpoch" as String)
                return
            }

            writer.writeLine(line)
        }
    }

    private static String determineSourceDateEpoch() {
        System.getenv('SOURCE_DATE_EPOCH') ?:
                LocalDate.now(ZoneOffset.UTC)
                        .atStartOfDay(ZoneOffset.UTC)
                        .toEpochSecond().toString()
    }
}
